libxc: osdep: add framework for abstracting access to dom0 OS hypervisor interfaces.
authorIan Campbell <ian.campbell@citrix.com>
Fri, 3 Dec 2010 09:36:46 +0000 (09:36 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 3 Dec 2010 09:36:46 +0000 (09:36 +0000)
This patch introduces the basic infrastructure and uses it for open
and close operations on privcmd, evtchn and gnttab devices.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson.citrix.com>
tools/libxc/Makefile
tools/libxc/xc_linux.c
tools/libxc/xc_minios.c
tools/libxc/xc_netbsd.c
tools/libxc/xc_private.c
tools/libxc/xc_private.h
tools/libxc/xc_solaris.c
tools/libxc/xenctrlosdep.h [new file with mode: 0644]

index 7d9307f53aca3149ce9daa93f5a6bc51b5ba6c33..18524084976b7e05e564567186ad4b53cdc3a3d0 100644 (file)
@@ -109,7 +109,7 @@ install: build
        $(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(LIBDIR)
        ln -sf libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so.$(MAJOR)
        ln -sf libxenctrl.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so
-       $(INSTALL_DATA) xenctrl.h xentoollog.h $(DESTDIR)$(INCLUDEDIR)
+       $(INSTALL_DATA) xenctrl.h xenctrlosdep.h xentoollog.h $(DESTDIR)$(INCLUDEDIR)
        $(INSTALL_PROG) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
        $(INSTALL_DATA) libxenguest.a $(DESTDIR)$(LIBDIR)
        ln -sf libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenguest.so.$(MAJOR)
index 13cb802d5dfd2dd01beeb4a43a75f61dbfd37713..5c9e70c06570ddbe7b2d92b43d7cca028d5f59a9 100644 (file)
@@ -29,7 +29,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle linux_privcmd_open(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/proc/xen/privcmd", O_RDWR);
@@ -37,7 +37,7 @@ int xc_interface_open_core(xc_interface *xch)
     if ( fd == -1 )
     {
         PERROR("Could not obtain handle on privileged command interface");
-        return -1;
+        return XC_OSDEP_OPEN_ERROR;
     }
 
     /* Although we return the file handle as the 'xc handle' the API
@@ -58,19 +58,21 @@ int xc_interface_open_core(xc_interface *xch)
         goto error;
     }
 
-    return fd;
+    xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+
+    return (xc_osdep_handle)fd;
 
  error:
     saved_errno = errno;
     close(fd);
     errno = saved_errno;
-
-    return -1;
+    return XC_OSDEP_OPEN_ERROR;
 }
 
-int xc_interface_close_core(xc_interface *xch)
+static int linux_privcmd_close(xc_interface *xch, xc_osdep_handle h)
 {
-    return close(xch->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 static int xc_map_foreign_batch_single(xc_interface *xch, uint32_t dom,
@@ -325,16 +327,27 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
                       (unsigned long)hypercall);
 }
 
+static struct xc_osdep_ops linux_privcmd_ops = {
+    .open = &linux_privcmd_open,
+    .close = &linux_privcmd_close,
+};
+
 #define DEVXEN "/dev/xen/"
 
-int xc_evtchn_open_core(xc_evtchn *xce)
+static xc_osdep_handle linux_evtchn_open(xc_evtchn *xce)
 {
-    return open(DEVXEN "evtchn", O_RDWR);
+    int fd = open(DEVXEN "evtchn", O_RDWR);
+    if ( fd == -1 )
+        return XC_OSDEP_OPEN_ERROR;
+
+    xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int linux_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    return close(xce->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 int xc_evtchn_fd(xc_evtchn *xce)
@@ -408,6 +421,11 @@ int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
     return write_exact(xce->fd, (char *)&port, sizeof(port));
 }
 
+static struct xc_osdep_ops linux_evtchn_ops = {
+    .open = &linux_evtchn_open,
+    .close = &linux_evtchn_close,
+};
+
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
@@ -443,14 +461,21 @@ void discard_file_cache(xc_interface *xch, int fd, int flush)
     errno = saved_errno;
 }
 
-int xc_gnttab_open_core(xc_gnttab *xcg)
+static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg)
 {
-    return open(DEVXEN "gntdev", O_RDWR);
+    int fd = open(DEVXEN "gntdev", O_RDWR);
+
+    if ( fd == -1 )
+        return XC_OSDEP_OPEN_ERROR;
+
+    xcg->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_gnttab_close_core(xc_gnttab *xcg)
+static int linux_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h)
 {
-    return close(xcg->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 void *xc_gnttab_map_grant_ref(xc_gnttab *xch, uint32_t domid, uint32_t ref, int prot)
@@ -602,6 +627,31 @@ int xc_gnttab_set_max_grants(xc_gnttab *xcg, uint32_t count)
     return 0;
 }
 
+static struct xc_osdep_ops linux_gnttab_ops = {
+    .open = &linux_gnttab_open,
+    .close = &linux_gnttab_close,
+};
+
+static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+    switch ( type )
+    {
+    case XC_OSDEP_PRIVCMD:
+        return &linux_privcmd_ops;
+    case XC_OSDEP_EVTCHN:
+        return &linux_evtchn_ops;
+    case XC_OSDEP_GNTTAB:
+        return &linux_gnttab_ops;
+    default:
+        return NULL;
+    }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+    .name = "Linux Native OS interface",
+    .init = &linux_osdep_init,
+};
+
 /*
  * Local variables:
  * mode: C
index d5f93f59eeb9297da529d0ba667b71c7fb428585..d822cf3e4796f480754d0d5288c1a939b334a12f 100644 (file)
@@ -49,14 +49,21 @@ extern void minios_evtchn_close_fd(int fd);
 
 extern struct wait_queue_head event_queue;
 
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle minios_privcmd_open(xc_interface *xch)
 {
-    return alloc_fd(FTYPE_XC);
+    int fd = alloc_fd(FTYPE_XC);
+
+    if ( fd == -1)
+        return XC_OSDEP_OPEN_ERROR;
+
+    xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_interface_close_core(xc_interface *xch)
+static int minios_privcmd_close(xc_interface *xch, xc_osdep_handle h)
 {
-    return close(xch->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 void minios_interface_close_fd(int fd)
@@ -172,20 +179,29 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
     return call.result;
 }
 
-int xc_evtchn_open_core(xc_evtchn *xce)
+static struct xc_osdep_ops minios_privcmd_ops = {
+    .open = &minios_privcmd_open,
+    .close = &minios_privcmd_close,
+};
+
+static xc_osdep_handle minios_evtchn_open(xc_evtchn *xce)
 {
     int fd = alloc_fd(FTYPE_EVTCHN), i;
+    if ( fd == -1 )
+        return XC_OSDEP_OPEN_ERROR;
     for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
        files[fd].evtchn.ports[i].port = -1;
         files[fd].evtchn.ports[i].bound = 0;
     }
     printf("evtchn_open() -> %d\n", fd);
-    return fd;
+    xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int minios_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    return close(xce->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 void minios_evtchn_close_fd(int fd)
@@ -368,6 +384,11 @@ int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
     return 0;
 }
 
+static struct xc_osdep_ops minios_evtchn_ops = {
+    .open = &minios_evtchn_open,
+    .close = &minios_evtchn_close,
+};
+
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush)
 {
@@ -375,17 +396,20 @@ void discard_file_cache(xc_interface *xch, int fd, int flush)
         fsync(fd);
 }
 
-int xc_gnttab_open_core(xc_gnttab *xcg)
+static xc_osdep_handle minios_gnttab_open(xc_gnttab *xcg)
 {
-    int fd;
-    fd = alloc_fd(FTYPE_GNTMAP);
+    int fd = alloc_fd(FTYPE_GNTMAP);
+    if ( fd == -1 )
+        return XC_OSDEP_OPEN_ERROR;
     gntmap_init(&files[fd].gntmap);
-    return fd;
+    xcg->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_gnttab_close_core(xc_gnttab *xcg)
+static int minios_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h)
 {
-    return close(xcg->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 void minios_gnttab_close_fd(int fd)
@@ -460,6 +484,31 @@ int xc_gnttab_set_max_grants(xc_gnttab *xcg,
     return ret;
 }
 
+static struct xc_osdep_ops minios_gnttab_ops = {
+    .open = &minios_gnttab_open,
+    .close = &minios_gnttab_close,
+};
+
+static struct xc_osdep_ops *minios_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+    switch ( type )
+    {
+    case XC_OSDEP_PRIVCMD:
+        return &minios_privcmd_ops;
+    case XC_OSDEP_EVTCHN:
+        return &minios_evtchn_ops;
+    case XC_OSDEP_GNTTAB:
+        return &minios_gnttab_ops;
+    default:
+        return NULL;
+    }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+    .name = "Minios Native OS interface",
+    .init = &minios_osdep_init,
+};
+
 /*
  * Local variables:
  * mode: C
index f60d0d41549eb0fd079b92caea93fb2ffd10b9ec..397c4fb71f7e27097f736594406fef4be236da35 100644 (file)
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle netbsd_privcmd_open(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/kern/xen/privcmd", O_RDWR);
@@ -32,7 +32,7 @@ int xc_interface_open_core(xc_interface *xch)
     if ( fd == -1 )
     {
         PERROR("Could not obtain handle on privileged command interface");
-        return -1;
+        return XC_OSDEP_OPEN_ERROR;
     }
 
     /* Although we return the file handle as the 'xc handle' the API
@@ -51,18 +51,21 @@ int xc_interface_open_core(xc_interface *xch)
         goto error;
     }
 
-    return fd;
+    xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+
+    return (xc_osinteface_handle)fd;
 
  error:
     saved_errno = errno;
     close(fd);
     errno = saved_errno;
-    return -1;
+    return XC_OSDEP_OPEN_ERROR;
 }
 
-int xc_interface_close_core(xc_interface *xch)
+static int netbsd_privcmd_close(xc_interface *xch, xc_osdep_handle h)
 {
-    return close(xch->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
@@ -179,16 +182,27 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
        return (hypercall->retval);
 }
 
+static struct xc_osdep_ops netbsd_privcmd_ops = {
+    .open = &netbsd_privcmd_open,
+    .close = &netbsd_privcmd_close,
+};
+
 #define EVTCHN_DEV_NAME  "/dev/xenevt"
 
-int xc_evtchn_open_core(xc_evtchn *xce)
+static xc_osdep_handle netbsd_evtchn_open(xc_evtchn *xce)
 {
-    return open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+    int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+    if ( fd == -1 )
+        return XC_OSDEP_OPEN_ERROR;
+
+    xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int netbsd_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    return close(xce->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 int xc_evtchn_fd(xc_evtchn *xce)
@@ -277,6 +291,11 @@ int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
     return write_exact(xce->fd, (char *)&port, sizeof(port));
 }
 
+static struct xc_osdep_ops netbsd_evtchn_ops = {
+    .open = &netbsd_evtchn_open,
+    .close = &netbsd_evtchn_close,
+};
+
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
@@ -312,6 +331,27 @@ void discard_file_cache(xc_interface *xch, int fd, int flush)
     errno = saved_errno;
 }
 
+static struct xc_osdep_ops *netbsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+    switch ( type )
+    {
+    case XC_OSDEP_PRIVCMD:
+        return &netbsd_privcmd_ops;
+    case XC_OSDEP_EVTCHN:
+        return &netbsd_evtchn_ops;
+    case XC_OSDEP_GNTTAB:
+        ERROR("GNTTAB interface not supported on this platform");
+        return NULL;
+    default:
+        return NULL;
+    }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+    .name = "Netbsd Native OS interface",
+    .init = &netbsd_osdep_init,
+};
+
 /*
  * Local variables:
  * mode: C
index 3ee500bbd19e2aff52569f1975dee8f54a37214c..3a0ce3509831d8526adfa96f84607e74cdbdd8f3 100644 (file)
 #include <pthread.h>
 #include <assert.h>
 
+/*
+ * Returns a (shallow) copy of the xc_osdep_info_t for the
+ * active OS interface.
+ *
+ * Returns:
+ *  0 - on success
+ * -1 - on error
+ */
+static int xc_osdep_get_info(xc_interface *xch, xc_osdep_info_t *info)
+{
+    int rc = -1;
+
+    *info = xc_osdep_info;
+
+    rc = 0;
+
+    return rc;
+}
+
+static void xc_osdep_put(xc_osdep_info_t *info)
+{
+}
+
 static struct xc_interface_core *xc_interface_open_common(xentoollog_logger *logger,
-                                              xentoollog_logger *dombuild_logger,
-                                              unsigned open_flags,
-                                              enum xc_interface_type type,
-                                              int (*open_core)(struct xc_interface_core *xch))
+                                                          xentoollog_logger *dombuild_logger,
+                                                          unsigned open_flags,
+                                                          enum xc_osdep_type type)
 {
     struct xc_interface_core xch_buf, *xch = &xch_buf;
 
@@ -44,6 +66,9 @@ static struct xc_interface_core *xc_interface_open_common(xentoollog_logger *log
     xch->error_handler   = logger;           xch->error_handler_tofree   = 0;
     xch->dombuild_logger = dombuild_logger;  xch->dombuild_logger_tofree = 0;
 
+    xch->ops_handle = XC_OSDEP_OPEN_ERROR;
+    xch->ops = NULL;
+
     if (!xch->error_handler) {
         xch->error_handler = xch->error_handler_tofree =
             (xentoollog_logger*)
@@ -61,30 +86,37 @@ static struct xc_interface_core *xc_interface_open_common(xentoollog_logger *log
     *xch = xch_buf;
 
     if (!(open_flags & XC_OPENFLAG_DUMMY)) {
-        xch->fd = open_core(xch);
-        if (xch->fd < 0)
+        if ( xc_osdep_get_info(xch, &xch->osdep) < 0 )
             goto err;
+
+        xch->ops = xch->osdep.init(xch, type);
+        if ( xch->ops == NULL )
+            goto err_put_iface;
+
+        xch->ops_handle = xch->ops->open(xch);
+        if (xch->ops_handle == XC_OSDEP_OPEN_ERROR)
+            goto err_put_iface;
     }
 
     return xch;
 
+err_put_iface:
+    xc_osdep_put(&xch->osdep);
  err:
     if (xch) xtl_logger_destroy(xch->error_handler_tofree);
     if (xch != &xch_buf) free(xch);
-    return 0;
+    return NULL;
 }
 
-static int xc_interface_close_common(xc_interface *xch, int (*close_core)(struct xc_interface_core *xch))
+static int xc_interface_close_common(xc_interface *xch)
 {
     int rc = 0;
 
     xtl_logger_destroy(xch->dombuild_logger_tofree);
     xtl_logger_destroy(xch->error_handler_tofree);
 
-    if (xch->fd >= 0) {
-        rc = close_core(xch);
-        if (rc) PERROR("Could not close hypervisor interface");
-    }
+    rc = xch->ops->close(xch, xch->ops_handle);
+    if (rc) PERROR("Could not close hypervisor interface");
 
     free(xch);
     return rc;
@@ -94,37 +126,45 @@ xc_interface *xc_interface_open(xentoollog_logger *logger,
                                 xentoollog_logger *dombuild_logger,
                                 unsigned open_flags)
 {
-    return xc_interface_open_common(logger, dombuild_logger, open_flags,
-                                    XC_INTERFACE_PRIVCMD, &xc_interface_open_core);
+    xc_interface *xch;
+
+    xch = xc_interface_open_common(logger, dombuild_logger, open_flags,
+                                   XC_OSDEP_PRIVCMD);
+
+    return xch;
 }
 
 int xc_interface_close(xc_interface *xch)
 {
-    return xc_interface_close_common(xch, &xc_interface_close_core);
+    return xc_interface_close_common(xch);
 }
 
 xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
                              unsigned open_flags)
 {
-    return xc_interface_open_common(logger, NULL, open_flags,
-                                    XC_INTERFACE_EVTCHN, &xc_evtchn_open_core);
+    xc_evtchn *xce;
+
+    xce = xc_interface_open_common(logger, NULL, open_flags,
+                                   XC_OSDEP_EVTCHN);
+
+    return xce;
 }
 
 int xc_evtchn_close(xc_evtchn *xce)
 {
-    return xc_interface_close_common(xce, &xc_evtchn_close_core);
+    return xc_interface_close_common(xce);
 }
 
 xc_gnttab *xc_gnttab_open(xentoollog_logger *logger,
                              unsigned open_flags)
 {
     return xc_interface_open_common(logger, NULL, open_flags,
-                                    XC_INTERFACE_GNTTAB, &xc_gnttab_open_core);
+                                    XC_OSDEP_GNTTAB);
 }
 
 int xc_gnttab_close(xc_gnttab *xcg)
 {
-    return xc_interface_close_common(xcg, &xc_gnttab_close_core);
+    return xc_interface_close_common(xcg);
 }
 
 static pthread_key_t errbuf_pkey;
index 8f3b2a2d0d93ddd2746accafe35383a340feb4c4..ccd1605288596e146cf4a3b6887e887e192d1173 100644 (file)
@@ -30,6 +30,7 @@
 #include <sys/ioctl.h>
 
 #include "xenctrl.h"
+#include "xenctrlosdep.h"
 
 #include <xen/sys/privcmd.h>
 
 */
 #define MAX_PAGECACHE_USAGE (4*1024)
 
-enum xc_interface_type {
-       XC_INTERFACE_PRIVCMD,
-       XC_INTERFACE_EVTCHN,
-       XC_INTERFACE_GNTTAB,
-};
-
 struct xc_interface_core {
-    enum xc_interface_type type;
+    enum xc_osdep_type type;
     int fd;
     int flags;
     xentoollog_logger *error_handler,   *error_handler_tofree;
@@ -80,6 +75,10 @@ struct xc_interface_core {
     struct xc_error last_error; /* for xc_get_last_error */
     FILE *dombuild_logger_file;
     const char *currently_progress_reporting;
+
+    xc_osdep_info_t  osdep;
+    xc_osdep_ops    *ops; /* backend operations */
+    xc_osdep_handle  ops_handle; /* opaque data for xc_osdep_ops */
 };
 
 void xc_report_error(xc_interface *xch, int code, const char *fmt, ...);
@@ -264,15 +263,6 @@ static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
 
 int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len);
 
-int xc_interface_open_core(struct xc_interface_core *xch); /* returns fd, logs errors */
-int xc_interface_close_core(struct xc_interface_core *xch); /* no logging */
-
-int xc_evtchn_open_core(struct xc_interface_core *xce); /* returns fd, logs errors */
-int xc_evtchn_close_core(struct xc_interface_core *xce); /* no logging */
-
-int xc_gnttab_open_core(struct xc_interface_core *xcg); /* returns fd, logs errors */
-int xc_gnttab_close_core(struct xc_interface_core *xcg); /* no logging */
-
 void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries);
index 40ee6f03ca6f1ca78158f931a295eaf7067cca6a..062b74249eb22a012238be434be124f32851e043 100644 (file)
@@ -25,7 +25,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle solaris_privcmd_open(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/dev/xen/privcmd", O_RDWR);
@@ -33,7 +33,7 @@ int xc_interface_open_core(xc_interface *xch)
     if ( fd == -1 )
     {
         PERROR("Could not obtain handle on privileged command interface");
-        return -1;
+        return XC_OSDEP_OPEN_ERROR;
     }
 
     /* Although we return the file handle as the 'xc handle' the API
@@ -52,17 +52,19 @@ int xc_interface_open_core(xc_interface *xch)
         goto error;
     }
 
-    return fd;
+    xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 
  error:
     saved_errno = errno;
     close(fd);
     errno = saved_errno;
-    return -1;
+    return XC_OSDEP_OPEN_ERROR;
 }
 
-int xc_interface_close(xc_interface *xch, int fd)
+static int solaris_privcmd_close(xc_interface *xch, xc_osdep_handle h)
 {
+    int fd = (int)h;
     return close(fd);
 }
 
@@ -154,7 +156,6 @@ mmap_failed:
     return NULL;
 }
 
-
 static int do_privcmd(xc_interface *xch, unsigned int cmd, unsigned long data)
 {
     return ioctl(xch->fd, cmd, data);
@@ -167,22 +168,29 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
                       (unsigned long)hypercall);
 }
 
-int xc_evtchn_open_core(xc_evtchn *xce)
+static struct xc_osdep_ops solaris_privcmd_ops = {
+    .open = &solaris_privcmd_open,
+    .close = &solaris_privcmd_close,
+};
+
+static xc_osdep_handle solaris_evtchn_open(xc_evtchn *xce)
 {
     int fd;
 
     if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 )
     {
         PERROR("Could not open event channel interface");
-        return -1;
+        return XC_OSDEP_OPEN_ERROR;
     }
 
-    return fd;
+    xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+    return (xc_osdep_handle)fd;
 }
 
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int solaris_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    return close(xce->fd);
+    int fd = (int)h;
+    return close(fd);
 }
 
 int xc_evtchn_fd(xc_evtchn *xce)
@@ -256,8 +264,44 @@ int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
     return write_exact(xce->fd, (char *)&port, sizeof(port));
 }
 
+static struct xc_osdep_ops solaris_evtchn_ops = {
+    .open = &solaris_evtchn_open,
+    .close = &solaris_evtchn_close,
+};
+
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
     // TODO: Implement for Solaris!
 }
+
+static struct xc_osdep_ops *solaris_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+    switch ( type )
+    {
+    case XC_OSDEP_PRIVCMD:
+        return &solaris_privcmd_ops;
+    case XC_OSDEP_EVTCHN:
+        return &solaris_evtchn_ops;
+    case XC_OSDEP_GNTTAB:
+        ERROR("GNTTAB interface not supported on this platform");
+        return NULL;
+    default:
+        return NULL;
+    }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+    .name = "Solaris Native OS interface",
+    .init = &solaris_osdep_init,
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/xenctrlosdep.h b/tools/libxc/xenctrlosdep.h
new file mode 100644 (file)
index 0000000..f807d0d
--- /dev/null
@@ -0,0 +1,90 @@
+/******************************************************************************
+ *
+ * Interface to OS specific low-level operations
+ *
+ * Copyright (c) 2010, Citrix Systems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * This interface defines the interactions between the Xen control
+ * libraries and the OS facilities used to communicate with the
+ * hypervisor.
+ */
+
+#ifndef XC_OSDEP_H
+#define XC_OSDEP_H
+
+/* Tell the Xen public headers we are a user-space tools build. */
+#ifndef __XEN_TOOLS__
+#define __XEN_TOOLS__ 1
+#endif
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <xen/sys/privcmd.h>
+
+enum xc_osdep_type {
+    XC_OSDEP_PRIVCMD,
+    XC_OSDEP_EVTCHN,
+    XC_OSDEP_GNTTAB,
+};
+
+/* Opaque handle internal to the backend */
+typedef unsigned long xc_osdep_handle;
+
+#define XC_OSDEP_OPEN_ERROR ((xc_osdep_handle)-1)
+
+struct xc_osdep_ops
+{
+    /* Opens an interface.
+     *
+     * Must return an opaque handle on success or
+     * XC_OSDEP_OPEN_ERROR on failure
+     */
+    xc_osdep_handle (*open)(xc_interface *xch);
+
+    int (*close)(xc_interface *xch, xc_osdep_handle h);
+};
+typedef struct xc_osdep_ops xc_osdep_ops;
+
+typedef xc_osdep_ops *(*xc_osdep_init_fn)(xc_interface *xch, enum xc_osdep_type);
+
+struct xc_osdep_info
+{
+    /* Describes this backend. */
+    const char *name;
+
+    /* Returns ops function. */
+    xc_osdep_init_fn init;
+};
+typedef struct xc_osdep_info xc_osdep_info_t;
+
+/* All backends, including the builtin backend, must supply this structure. */
+extern xc_osdep_info_t xc_osdep_info;
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */